package com.aizhixin.lab.project.course.service;

import com.aizhixin.lab.account.dto.AccountDTO;
import com.aizhixin.lab.common.core.ApiReturnConstants;
import com.aizhixin.lab.common.core.DataValidity;
import com.aizhixin.lab.common.utils.ExcelUtil;
import com.aizhixin.lab.common.utils.PageJdbcUtil;
import com.aizhixin.lab.company.entity.Classes;
import com.aizhixin.lab.company.entity.User;
import com.aizhixin.lab.company.repository.ClassesRepository;
import com.aizhixin.lab.company.repository.UserRepository;
import com.aizhixin.lab.jsrun.domian.CodeDomain;
import com.aizhixin.lab.jsrun.service.JsRunService;
import com.aizhixin.lab.project.course.domain.*;
import com.aizhixin.lab.project.course.domain.StuAnswerParamsDomain;
import com.aizhixin.lab.project.course.domain.StuAnswerSaveDomain;
import com.aizhixin.lab.project.course.entity.*;
import com.aizhixin.lab.project.course.repository.*;
import com.aizhixin.lab.project.template.domain.ExercisesDomain;
import com.aizhixin.lab.project.template.domain.ExercisesFileDomain;
import com.aizhixin.lab.project.template.domain.ExercisesQuestionChoiceDomain;
import com.aizhixin.lab.project.template.entity.Exercises;
import com.aizhixin.lab.project.template.entity.ExercisesChoice;
import com.aizhixin.lab.project.template.entity.ExercisesFile;
import com.aizhixin.lab.project.template.entity.TaskWorkOrder;
import com.aizhixin.lab.project.template.repository.ExercisesChoiceRepository;
import com.aizhixin.lab.project.template.repository.ExercisesFileRepository;
import com.aizhixin.lab.project.template.repository.ExercisesRepository;
import com.aizhixin.lab.project.template.repository.TaskWorkOrderRepository;
import com.aizhixin.lab.statistics.util.ReportUtils;
import com.aizhixin.lab.task.core.ExerciseType;
import com.aizhixin.lab.task.core.TaskInforCode;
import com.aizhixin.lab.task.domain.*;
import com.aizhixin.lab.task.entity.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@Transactional
public class TeacherExercisesService {
    @Autowired
    private TeacherExercisesRepository exercisesRepository;
    @Autowired
    private TeacherExercisesChoiceRepository choiceRepository;
    @Autowired
    private TeacherExercisesFileRepository fileRepository;
    @Autowired
    private TaskWorkOrderRepository taskWorkOrderRepository;
    @Autowired
    private TeacherTaskWorkOrderRepository teacherTaskWorkOrderRepository;
    @Autowired
    private ProjectGroupTaskRepository taskRepository;
    @Autowired
    private ProjectClassRepository projectClassRepository;
    @Autowired
    private ClassesRepository classesRepository;
    @Autowired
    private ExercisesStuAnswerRepository exercisesStuAnswerRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private ExerciseStuCodeRepository exerciseStuCodeRepository;
    @Autowired
    private ExercisesStuStatisticsRepository exercisesStuStatisticsRepository;
    @Autowired
    private JsRunService jsRunService;
    @Autowired
    private ExercisesStuFileRepository exercisesStuFileRepository;
    @Autowired
    private PageJdbcUtil pageJdbcUtil;
    public void delete(String id) {
        exercisesRepository.deleteByTaskId(id);
    }

    public Map<String, Object> releaseExercises(ReleaseExercisesDomain domain) {
        Map<String, Object> result = new HashMap<>();
        List<ProjectGroupTask> projectGroupTasks = new ArrayList<>();
        for (String projectClassId : domain.getProjectClassId()) {
            List<ProjectGroupTask> projectGroupTaskList;
            if (!StringUtils.isEmpty(domain.getWorkOrderId())) {
                projectGroupTaskList = taskRepository.findByWorkOrderIdAndProjectClassIdAndDeleteFlag(domain.getWorkOrderId(), projectClassId, DataValidity.VALID.getState());
            } else {
                projectGroupTaskList = taskRepository.findByTaskIdAndProjectClassIdAndDeleteFlagAndWorkOrderIdIsNull(domain.getTaskId(), projectClassId, DataValidity.VALID.getState());
            }
            if (projectGroupTaskList.size() == 0) {
                ProjectClass projectClass = projectClassRepository.findByIdAndDeleteFlag(projectClassId, DataValidity.VALID.getState());
                Classes classes = classesRepository.findById(projectClass.getClassId());
                result.put(ApiReturnConstants.SUCCESS, false);
                result.put(ApiReturnConstants.ERROR, classes.getName() + "未发布任务,请先发布任务后在发布习题");
                return result;
            }
            projectGroupTaskList.forEach(projectGroupTask -> {
                projectGroupTask.setIsReleaseExercises(true);
                projectGroupTask.setExercisesName(domain.getExercisesName());
                projectGroupTask.setIsSetTime(domain.getIsSetTime());
                projectGroupTask.setDuration(domain.getDuration());
                projectGroupTasks.add(projectGroupTask);
            });

        }
        taskRepository.save(projectGroupTasks);
        result.put(ApiReturnConstants.SUCCESS, true);
        result.put(ApiReturnConstants.MESSAGE, "发布成功");
        return result;
    }

    public Map<String, Object> saveQuestionList(List<ExercisesDomain> domainList, AccountDTO dto) {
        Map<String, Object> result = new HashMap<String, Object>();
        int i = 1;
        for (ExercisesDomain domain : domainList) {
            if (domain.getTaskId().isEmpty()) {
                result.put(ApiReturnConstants.SUCCESS, false);
                result.put(ApiReturnConstants.ERROR, "任务id不能为空！");
                return result;
            }
            boolean isFileEmpty = false;
            if (domain.getAccessorylist().isEmpty()) {
                isFileEmpty = true;
            }
            if (StringUtils.isEmpty(domain.getAnswer())) {
                result.put(ApiReturnConstants.SUCCESS, false);
                result.put(ApiReturnConstants.ERROR, "第" + i + "题 答案不能为空！");
                return result;
            }
            if (domain.getQuestionContent().isEmpty() && !isFileEmpty) {
                result.put(ApiReturnConstants.SUCCESS, false);
                result.put(ApiReturnConstants.ERROR, "第" + i + "题 题目题干和题干附件不能同时为空！");
                return result;
            }
            if ((ExerciseType.MULTIPLE.getIntValue().equals(domain.getQuestionType()) || ExerciseType.SINGLE.getIntValue().equals(domain.getQuestionType())) && domain.getChoicelist() == null) {
                result.put(ApiReturnConstants.SUCCESS, false);
                result.put(ApiReturnConstants.ERROR, "第" + i + "题 客观题选项不能够为空！");
                return result;
            }

            //如果题目类型为编程题选择题则必须传语言类型
            if (domain.getQuestionType() == 60 && domain.getLanguage() == null) {
                result.put(ApiReturnConstants.SUCCESS, false);
                result.put(ApiReturnConstants.ERROR, "第" + i + "题 语言种类必须选择！");
                return result;
            }
        }
        if (domainList.size() > 0) {
            ExercisesDomain exercisesDomain = domainList.get(0);
            exercisesRepository.deleteByTaskId(exercisesDomain.getTaskId());
        }
        for (ExercisesDomain domain : domainList) {
            save(domain, dto.getId());
        }
        result.put(ApiReturnConstants.SUCCESS, true);
        result.put(ApiReturnConstants.DATA, "保存成功");
        return result;
    }


    public void save(ExercisesDomain domain, Long createdBy) {
        TeacherExercises exercises = new TeacherExercises();
        Boolean isNew = true;
        if (StringUtils.isEmpty(domain.getId())) {
            domain.setId(UUID.randomUUID().toString());
            isNew = false;
        }
        BeanUtils.copyProperties(domain, exercises);
        exercises.setCreatedBy(createdBy);
        List<TeacherExercisesChoice> choiceList = new ArrayList<>();

        if (ExerciseType.MULTIPLE.getIntValue().equals(domain.getQuestionType()) || ExerciseType.SINGLE.getIntValue().equals(domain.getQuestionType()) || ExerciseType.JUDGMENT.getIntValue().equals(domain.getQuestionType())) {
            if (null != domain.getChoicelist() && 0 < domain.getChoicelist().size()) {
//                    List<ExercisesFile> fileList = new ArrayList<ExercisesFile>();
                for (ExercisesQuestionChoiceDomain choiceDomain : domain.getChoicelist()) {
                    TeacherExercisesChoice choice = new TeacherExercisesChoice();
                    if (StringUtils.isEmpty(choiceDomain.getId())) {
                        choiceDomain.setId(UUID.randomUUID().toString());
                    }
//                    String choiceId = UUID.randomUUID().toString();
                    choice.setId(choiceDomain.getId());
                    choice.setOption(choiceDomain.getOption());
                    choice.setChoiceContent(choiceDomain.getChoiceContent());
                    choice.setExercisesQuestionId(domain.getId());
                    choiceList.add(choice);
//                        if (!choiceDomain.getAccessorylist().isEmpty()) {
//                            for (TaskFileDomain accessoryDomain : choiceDomain.getAccessorylist()) {
//                                ExercisesFile accessory = new ExercisesFile();
//                                accessory.setId(UUID.randomUUID().toString());
//                                accessory.setTaskId(domain.getTaskId());
//                                accessory.setTaskQuestionId(questionId);
//                                accessory.setTaskChoiceId(choiceId);
//                                accessory.setSource(TaskInforCode.FILE_FROM_CHOICE);
//                                accessory.setFileName(accessoryDomain.getFileName());
//                                accessory.setFileUrl(accessoryDomain.getFileUrl());
//                                accessory.setFileKey(accessoryDomain.getFileKey());
//                                accessory.setOrderNum(accessoryDomain.getOrderNum());
//                                fileList.add(accessory);
//                            }
//                        }
                }
            }
        }
        List<TeacherExercisesFile> fileDomainList = new ArrayList<>();
        if (domain.getAccessorylist().size() > 0)
            for (ExercisesFileDomain exercisesFileDomain : domain.getAccessorylist()) {
                TeacherExercisesFile exercisesFile = new TeacherExercisesFile();
                exercisesFile.setId(UUID.randomUUID().toString());
                exercisesFile.setTaskId(domain.getTaskId());
                exercisesFile.setExercisesQuestionId(domain.getId());
//            accessory.setTaskChoiceId(choiceId);
//            accessory.setSource(TaskInforCode.FILE_FROM_CHOICE);
                exercisesFile.setFileName(exercisesFileDomain.getFileName());
                exercisesFile.setFileUrl(exercisesFileDomain.getFileUrl());
                exercisesFile.setFileKey(exercisesFileDomain.getFileKey());
                exercisesFile.setOrderNum(exercisesFileDomain.getOrderNum());
//                fileRepository.save(exercisesFile);
                fileDomainList.add(exercisesFile);
            }
        if (isNew) {
            fileRepository.deleteByExercisesQuestionId(domain.getId());
            choiceRepository.deleteByExercisesQuestionId(domain.getId());
        }
        fileRepository.save(fileDomainList);
        choiceRepository.save(choiceList);
        exercisesRepository.save(exercises);
    }

    public List<ExercisesDomain> findAllQuestions(String id) {
        List<TeacherExercises> exercises = exercisesRepository.findByTaskId(id);
        List<ExercisesDomain> domainList = new ArrayList<>();
        exercises.forEach(item -> {
            ExercisesDomain exercisesDomain = new ExercisesDomain();
            BeanUtils.copyProperties(item, exercisesDomain);
            if (ExerciseType.MULTIPLE.getIntValue().equals(item.getQuestionType()) || ExerciseType.SINGLE.getIntValue().equals(item.getQuestionType()) || ExerciseType.JUDGMENT.getIntValue().equals(item.getQuestionType())) {
                List<TeacherExercisesChoice> exercisesChoiceList = choiceRepository.findByExercisesQuestionIdOrderByOption(item.getId());
                List<ExercisesQuestionChoiceDomain> questionChoiceDomainList = new ArrayList<>();
                exercisesChoiceList.forEach(choice -> {
                    ExercisesQuestionChoiceDomain domain = new ExercisesQuestionChoiceDomain();
                    BeanUtils.copyProperties(choice, domain);
                    questionChoiceDomainList.add(domain);
                });
                if (ExerciseType.JUDGMENT.getIntValue().equals(item.getQuestionType())) {
                    Collections.reverse(questionChoiceDomainList);
                }
                exercisesDomain.setChoicelist(questionChoiceDomainList);
            }
            List<ExercisesFileDomain> fileDomainList = new ArrayList<>();
            List<TeacherExercisesFile> exercisesFileList = fileRepository.findByExercisesQuestionId(item.getId());
            exercisesFileList.forEach(file -> {
                ExercisesFileDomain exercisesFileDomain = new ExercisesFileDomain();
                BeanUtils.copyProperties(file, exercisesFileDomain);
                fileDomainList.add(exercisesFileDomain);
            });
            exercisesDomain.setAccessorylist(fileDomainList);
            domainList.add(exercisesDomain);
        });
        return domainList;
    }

    public String exportExercises(MultipartFile file, Long createBy) throws IOException {
        ExcelUtil excelUtil = new ExcelUtil(file.getInputStream(), "2003");
        Map<String, Integer> map = new HashMap<>();
        Sheet sheet = excelUtil.getWorkbook().getSheetAt(0);
        StringBuffer stringBuffer = new StringBuffer();
        List<TeacherExercises> list = new ArrayList<>();
        List<TeacherExercisesChoice> choiceList = new ArrayList<>();
        int rows = sheet.getLastRowNum();
        for (int r = 1; r <= rows; r++) {

            Row row = sheet.getRow(r);
            if (StringUtils.isEmpty(excelUtil.getCellValueToString(row.getCell(0)))) {
                continue;
            }
            TeacherExercises domain = new TeacherExercises();
            domain.setId(UUID.randomUUID().toString());
            domain.setQuestionType(Integer.parseInt(excelUtil.getCellValueToString(row.getCell(0))));
            TeacherTaskWorkOrder taskWorkOrder = teacherTaskWorkOrderRepository.findByWorkOrderNameLikeIgnoreCaseAndDeleteFlagAndCreatedBy("%" + excelUtil.getCellValueToString(row.getCell(1)).trim() + "%", 0, 1927L);
            try {
                domain.setTaskId(taskWorkOrder.getId());
                domain.setOrderNum(returnOrderNum(map, domain.getTaskId()));
            } catch (NullPointerException e) {
                throw new NullPointerException("第" + r + "行工单名称不存在请修改后重试");
            }

            domain.setQuestionContent(excelUtil.getCellValueToString(row.getCell(2)));
            domain.setAnalysis(excelUtil.getCellValueToString(row.getCell(3)));
            domain.setAnswer(excelUtil.getCellValueToString(row.getCell(4)));
            domain.setCreatedBy(createBy);
            if (domain.getQuestionType() == 10 || domain.getQuestionType() == 20) {
                for (int j = 6; j < Integer.parseInt(excelUtil.getCellValueToString(row.getCell(5))) + 6; j++) {
                    TeacherExercisesChoice exercisesChoice = new TeacherExercisesChoice();
                    exercisesChoice.setId(UUID.randomUUID().toString());
                    exercisesChoice.setExercisesQuestionId(domain.getId());
                    exercisesChoice.setOption(((char) ('A' + j - 6)) + "");
                    exercisesChoice.setChoiceContent(excelUtil.getCellValueToString(row.getCell(j)));
                    choiceList.add(exercisesChoice);
                }
            }
            if (domain.getQuestionType() == 30) {
                choiceList.addAll(returnTF(domain.getId()));
            }
            list.add(domain);
        }

        exercisesRepository.save(list);
        choiceRepository.save(choiceList);

        return stringBuffer.toString();
    }

    private List<TeacherExercisesChoice> returnTF(String id) {
        List<TeacherExercisesChoice> choiceList = new ArrayList<>();
        TeacherExercisesChoice exercisesChoice = new TeacherExercisesChoice();
        exercisesChoice.setId(UUID.randomUUID().toString());
        exercisesChoice.setExercisesQuestionId(id);
        exercisesChoice.setOption("T");
        exercisesChoice.setChoiceContent("正确");
        choiceList.add(exercisesChoice);
        TeacherExercisesChoice exercisesChoice1 = new TeacherExercisesChoice();
        exercisesChoice1.setId(UUID.randomUUID().toString());
        exercisesChoice1.setExercisesQuestionId(id);
        exercisesChoice1.setOption("F");
        exercisesChoice1.setChoiceContent("错误");
        choiceList.add(exercisesChoice1);
        return choiceList;
    }


    private Integer returnOrderNum(Map<String, Integer> map, String id) {
        Integer integer = map.get(id);
        if (Objects.isNull(integer)) {
            map.put(id, 1);
            return 1;
        } else {
            integer++;
            map.put(id, integer);
            return integer;
        }
    }
    private static int[] randomCommon(int min, int max, int n) {
        if (n > (max - min + 1) || max < min) {
            return null;
        }
        int[] result = new int[n];
        int count = 0;
        while (count < n) {
            int num = (int) (Math.random() * (max - min)) + min;
            boolean flag = true;
            for (int j = 0; j < n; j++) {
                if (num == result[j]) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                result[count] = num;
                count++;
            }
        }
        return result;
    }
    private static int getMyInt(int a, int b) {
        return (((double) a / (double) b) > (a / b) ? a / b + 1 : a / b);
    }
    public void saveExercisesAnswer(StuAnswerSaveDomain domain, Long createBy) {
        exercisesStuAnswerRepository.deleteByGroupTaskIdAndStuId(domain.getGroupTaskId(), createBy);
//        List<ExercisesStuAnswer> exercisesStuAnswerList = new ArrayList<>();
//        for (StuAnswerParamsDomain stuAnswerParamsDomain : domain.getAnswerList()) {
//            ExercisesStuAnswer exercisesStuAnswer = new ExercisesStuAnswer();
//            BeanUtils.copyProperties(stuAnswerParamsDomain, exercisesStuAnswer);
//            exercisesStuAnswer.setId(UUID.randomUUID().toString());
////            exercisesStuAnswer.setExercisesId(stuAnswerParamsDomain.getExercisesId());
////            exercisesStuAnswer.setId(UUID.randomUUID().toString());
//            exercisesStuAnswer.setGroupTaskId(domain.getGroupTaskId());
//            try {
//                exercisesStuAnswer.setStuAnswer(stuAnswerParamsDomain.getStuAnswer().trim());
//            } catch (NullPointerException e) {
//
//            }
//            exercisesStuAnswer.setStuId(createBy);
//            exercisesStuAnswer.setExercisesId(stuAnswerParamsDomain.getExercisesId());
//            exercisesStuAnswerList.add(exercisesStuAnswer);
//        }

        List<StuAnswerParamsDomain> answerList = domain.getAnswerList();
        List<ExercisesStuAnswer> stuAnswers = new ArrayList<>();
        List<ExercisesStuFile> accessorys = new ArrayList<>();
        List<ExerciseStuCode> taskStuCodeList = new ArrayList<>();
        List<String> ids = new ArrayList<>();
//        deleteByTaskStuInforId(taskStuInforId);

        //编程题处理，每次每次提交的编程题都会存储
        for (StuAnswerParamsDomain aitem : answerList) {
            TeacherExercises teacherExercises = exercisesRepository.findOne(aitem.getExercisesId());

            if (aitem.getQuestionType() != null && 60 == aitem.getQuestionType()) {
                if (aitem.getStuAnswerAccessorylist()!=null&&aitem.getStuAnswerAccessorylist().size()>0){
                    continue;
                }
                ExerciseStuCode taskStuCode = new ExerciseStuCode();
                taskStuCode.setId(UUID.randomUUID().toString());
                taskStuCode.setExercisesQuestionId(aitem.getExercisesId());
                taskStuCode.setCodeRowNum(Integer.parseInt(aitem.getCodeRowNum()));
                taskStuCode.setSubmitCode(aitem.getRunCode());
                taskStuCode.setSubmitTime(new Date());
                taskStuCode.setLanguage(aitem.getLanguage());
                taskStuCode.setStuId(createBy.toString());
                if (domain.isCommit()) {
                    taskStuCode.setTaskStatus(TaskInforCode.TASK_STATUS_UNCOMMIT);
                    CodeDomain codeDomain = new CodeDomain();
                    codeDomain.setCode(aitem.getRunCode());
                    codeDomain.setLang(aitem.getLanguage());
                    Map<String, String> resMap = jsRunService.codeRunDetection(codeDomain);
                    if (!resMap.isEmpty()) {
                        Random random = new Random();
                        ExercisesStuStatistics taskStuStatistics = new ExercisesStuStatistics();
                        taskStuStatistics.setId(UUID.randomUUID().toString());
                        taskStuStatistics.setCodeAdvise(resMap.get("verif"));
                        taskStuStatistics.setRunResult(resMap.get("runResult"));
                        Integer space = Integer.parseInt(aitem.getCodeRowNum()) / 1024 * 1000;
                        taskStuStatistics.setOccupySpace(space == 0 ? random.nextInt(50) + 1 : space);
                        taskStuStatistics.setExecuteTime(resMap.get("executeTime"));
                        taskStuStatistics.setExercisesQuestionId(aitem.getExercisesId());
                        taskStuStatistics.setStuId(createBy.toString());
                        taskStuStatistics.setViolationNum(Integer.parseInt(String.valueOf(resMap.get("violationNum"))));
                        String[] codeNum = teacherExercises.getReferenceCode().split("\n");
                        Integer num = Integer.parseInt(aitem.getCodeRowNum()) - codeNum.length;

                        if (teacherExercises.getAnswer().equals(taskStuStatistics.getRunResult())) {
                            Integer score = randomCommon(95, 99, 1)[0];
                            taskStuStatistics.setScore(randomCommon(95, 99, 1)[0]);
                            if (num < 0) {
                                taskStuStatistics.setScore(score + num * 10 < 0 ? 10 : score + num * 10);
                            }
                        } else if (num >= 0) {
                            taskStuStatistics.setScore(randomCommon(60, 79, 1)[0]);
                        } else if (num < 0) {
                            Integer score = randomCommon(20, 59, 1)[0];
                            taskStuStatistics.setScore(score + num * 10 < 0 ? 10 : score + num * 10);
                        }
                        taskStuCode.setScore(taskStuStatistics.getScore());
                        taskStuCode.setRunResult(taskStuStatistics.getRunResult());
                        taskStuCode.setIsError(taskStuStatistics.getViolationNum());

                        ExercisesStuAnswer answer = new ExercisesStuAnswer();
                        String answerId = UUID.randomUUID().toString();
                        answer.setId(answerId);
                        answer.setStuAnswer(aitem.getRunCode());
                        answer.setComment(taskStuStatistics.getScore() + "");
                        answer.setGroupTaskId(domain.getGroupTaskId());
                        answer.setStuId(createBy);
//                        answer.setStuName(account.getName());
                        answer.setExercisesId(aitem.getExercisesId());
                        answer.setDeleteFlag(DataValidity.VALID.getState());
                        answer.setRunCode(aitem.getRunCode());
                        answer.setRunResult(aitem.getRunResult());
//                        answer.setReleaseTaskId(domain.getReleaseTaskId());
                        answer.setLanguage(aitem.getLanguage());
                        stuAnswers.add(answer);

                        exercisesStuStatisticsRepository.deleteByExercisesQuestionIdAndStuId(taskStuStatistics.getExercisesQuestionId(), taskStuStatistics.getStuId());
                        exercisesStuStatisticsRepository.save(taskStuStatistics);
                    }
                } else {
                    Integer score = 0;
                    CodeDomain codeDomain = new CodeDomain();
                    codeDomain.setCode(aitem.getRunCode());
                    codeDomain.setLang(aitem.getLanguage());
                    Map<String, String> resMap = jsRunService.codeRunDetection(codeDomain);
                    String[] codeNum = teacherExercises.getReferenceCode().split("\n");
                    Integer num = Integer.parseInt(aitem.getCodeRowNum()) - codeNum.length;
                    if (teacherExercises.getAnswer().equals(resMap.get("runResult"))) {
                        score = +randomCommon(95, 99, 1)[0];
                        if (num < 0) {
                            score = +score + num * 10 < 0 ? 10 : score + num * 10;
                        }
                    } else if (num >= 0) {
                        score = +randomCommon(60, 79, 1)[0];
                    } else if (num < 0) {
                        score = +randomCommon(20, 59, 1)[0];
                        score = +score + num * 10 < 0 ? 10 : score + num * 10;
                    }

                    taskStuCode.setScore(score);
                    taskStuCode.setRunResult(resMap.get("runResult"));
                    taskStuCode.setIsError(Integer.parseInt(String.valueOf(resMap.get("violationNum"))));

                    ExercisesStuAnswer answer = new ExercisesStuAnswer();
                    String answerId = UUID.randomUUID().toString();
                    answer.setId(answerId);
                    answer.setStuAnswer(aitem.getRunCode());
                    answer.setGroupTaskId(domain.getGroupTaskId());
                    answer.setStuId(createBy);
//                    answer.setStuName(account.getName());
                    answer.setExercisesId(aitem.getExercisesId());
                    answer.setDeleteFlag(DataValidity.VALID.getState());
//                    answer.setReleaseTaskId(domain.getReleaseTaskId());
                    answer.setLanguage(aitem.getLanguage());

                    stuAnswers.add(answer);
                    taskStuCode.setTaskStatus(TaskInforCode.TASK_STATUS_PENDING);
                }
                taskStuCodeList.add(taskStuCode);
            }
            String answerId = UUID.randomUUID().toString();
            //简答题关键字匹配
            if (aitem.getQuestionType() != null && 70 == aitem.getQuestionType()) {
                ExercisesStuAnswer taskStuAnswer = new ExercisesStuAnswer();
                int stuScore = 0;
                if (teacherExercises.getKeyword() != null) {
                    String[] keyWord = teacherExercises.getKeyword().split(",");
                    for (String str : keyWord) {
                        int score = 90;
                        if (keyWord.length >= 0) {
                            score = getMyInt(score, keyWord.length);
                        }
                        if (aitem.getStuAnswer() == null) {
                            continue;
                        }
                        if (aitem.getStuAnswer().contains(str)) {
                            stuScore += score;
                        }

                    }
                }
                taskStuAnswer.setId(answerId);
                taskStuAnswer.setComment(stuScore + "");
                taskStuAnswer.setExercisesId(aitem.getExercisesId());
//                taskStuAnswer.setReleaseTaskId(domain.getReleaseTaskId());
                taskStuAnswer.setGroupTaskId(domain.getGroupTaskId());
                taskStuAnswer.setCreatedDate(new Date());
                taskStuAnswer.setDeleteFlag(DataValidity.VALID.getState());
                taskStuAnswer.setStuAnswer(aitem.getStuAnswer());
                taskStuAnswer.setStuId(createBy);
//                taskStuAnswer.setStuName(account.getUserName());
                stuAnswers.add(taskStuAnswer);
            } else if (aitem.getQuestionType() != null && 70 != aitem.getQuestionType() && 60 != aitem.getQuestionType()) {
                ids.add(answerId);
                ExercisesStuAnswer answer = new ExercisesStuAnswer();
                answer.setId(answerId);
                answer.setGroupTaskId(domain.getGroupTaskId());
                answer.setStuId(createBy);
//                answer.setStuName(account.getName());
                answer.setExercisesId(aitem.getExercisesId());
                answer.setStuAnswer(aitem.getStuAnswer());
                answer.setDeleteFlag(DataValidity.VALID.getState());
                answer.setRunCode(aitem.getRunCode());
                answer.setRunResult(aitem.getRunResult());
//                answer.setReleaseTaskId(domain.getReleaseTaskId());
                answer.setLanguage(aitem.getLanguage());
                stuAnswers.add(answer);
            }
            if (aitem.getStuAnswerAccessorylist() != null && aitem.getStuAnswerAccessorylist().size() > 0) {
                for (StuAccessoryParamsDomain saitem : aitem.getStuAnswerAccessorylist()) {
                    ExercisesStuFile accessory = new ExercisesStuFile();
                    accessory.setId(UUID.randomUUID().toString());
                    accessory.setGroupTaskId(domain.getGroupTaskId());
                    accessory.setExercisesQuestionId(aitem.getExercisesId());
                    accessory.setStuAnswerId(answerId);
                    accessory.setStuId(createBy);
                    accessory.setFileName(saitem.getFileName());
                    accessory.setFileUrl(saitem.getFileUrl());
                    accessory.setFileKey(saitem.getFileKey());
                    accessorys.add(accessory);
                }
            }
        }
        exercisesStuFileRepository.deleteByGroupTaskIdAndStuId(domain.getGroupTaskId(),createBy);
        if (!accessorys.isEmpty()) {
//            taskStuFileService.deleteByReleaseTaskIdAndStuId(domain.getReleaseTaskId(),account.getId());
            exercisesStuFileRepository.save(accessorys);
        }
        if (!taskStuCodeList.isEmpty()) {
            exerciseStuCodeRepository.save(taskStuCodeList);
        }
        exercisesStuAnswerRepository.save(stuAnswers);
        ProjectGroupTask one = taskRepository.findOne(domain.getGroupTaskId());
        if (domain.isCommit()) {
            one.setExercisesStatus(TaskInforCode.TASK_STATUS_PENDING);
            one.setExercisesCommitTime(new Date());
            auto(domain.getGroupTaskId(), createBy);
        } else {
            one.setExercisesStatus(TaskInforCode.TASK_STATUS_UNCOMMIT);
        }
        taskRepository.save(one);
    }

    @Async
    public void auto(String groupTaskId, Long createBy) {
        List<ExercisesStuAnswer> exercisesStuAnswerList = exercisesStuAnswerRepository.findByGroupTaskIdAndStuId(groupTaskId, createBy);
        List<ExercisesStuAnswer> exercisesStuAnswers = new ArrayList<>();
        exercisesStuAnswerList.forEach(exercisesStuAnswer -> {
            TeacherExercises teacherExercises = exercisesRepository.findOne(exercisesStuAnswer.getExercisesId());
            if (exercisesStuAnswer.getStuAnswer().equals(teacherExercises.getAnswer())) {
                exercisesStuAnswer.setIsCorrect(1);
                exercisesStuAnswer.setComment(100+"");
            } else {
                exercisesStuAnswer.setIsCorrect(0);
                exercisesStuAnswer.setComment(0+"");
            }
            exercisesStuAnswers.add(exercisesStuAnswer);
        });
        exercisesStuAnswerRepository.save(exercisesStuAnswers);

    }

    //获取同习题下的学生列表
    public List<StuInfoDomain> getStuList(String id) {
        ProjectGroupTask projectGroupTask = taskRepository.findOne(id);
        List<ProjectGroupTask> projectGroupTaskList;
        if (StringUtils.isEmpty(projectGroupTask.getWorkOrderId())) {
            projectGroupTaskList = taskRepository.findByTaskIdAndProjectClassIdAndDeleteFlagAndWorkOrderIdIsNull(projectGroupTask.getTaskId(), projectGroupTask.getProjectClassId(), DataValidity.VALID.getState());
        } else {
            projectGroupTaskList = taskRepository.findByWorkOrderIdAndProjectClassIdAndDeleteFlag(projectGroupTask.getWorkOrderId(), projectGroupTask.getProjectClassId(), DataValidity.VALID.getState());
        }
        List<StuInfoDomain> stuInfoDomainList = new ArrayList<>();
        projectGroupTaskList.forEach(projectGroupTask1 -> {
            StuInfoDomain stuInfoDomain = new StuInfoDomain();
            User user = userRepository.findOne(projectGroupTask1.getStuId());
            stuInfoDomain.setJobNum(user.getJobNum());
            stuInfoDomain.setStuName(user.getName());
            Classes classes = classesRepository.findById(user.getClassId());
            stuInfoDomain.setClassName(classes.getName());
            stuInfoDomain.setTaskStatus(projectGroupTask1.getTaskStatus());
            stuInfoDomain.setComment(projectGroupTask1.getExercisesComment());
            stuInfoDomain.setCommitTime(projectGroupTask1.getExercisesCommitTime());
            stuInfoDomain.setProjectClassId(projectGroupTask1.getProjectClassId());
            stuInfoDomain.setGrade(projectGroupTask1.getExercisesFinalGrade());
            stuInfoDomainList.add(stuInfoDomain);
        });
        return stuInfoDomainList;
    }

    //学生获取试题及答案
    public List<ExercisesDomain> findStuAllQuestionsAndAnswer(String id) {
        ProjectGroupTask projectGroupTask = taskRepository.findOne(id);
        List<TeacherExercises> exercises;
        if (projectGroupTask.getTaskType() == 1) {
            exercises = exercisesRepository.findByTaskId(projectGroupTask.getWorkOrderId());
        } else {
            exercises = exercisesRepository.findByTaskId(projectGroupTask.getTaskId());
        }
        List<ExercisesDomain> domainList = new ArrayList<>();
        exercises.forEach(item -> {
            ExercisesDomain exercisesDomain = new ExercisesDomain();
            BeanUtils.copyProperties(item, exercisesDomain);
            if (ExerciseType.MULTIPLE.getIntValue().equals(item.getQuestionType()) || ExerciseType.SINGLE.getIntValue().equals(item.getQuestionType()) || ExerciseType.JUDGMENT.getIntValue().equals(item.getQuestionType())) {
                List<TeacherExercisesChoice> exercisesChoiceList = choiceRepository.findByExercisesQuestionIdOrderByOption(item.getId());
                List<ExercisesQuestionChoiceDomain> questionChoiceDomainList = new ArrayList<>();
                exercisesChoiceList.forEach(choice -> {
                    ExercisesQuestionChoiceDomain domain = new ExercisesQuestionChoiceDomain();
                    BeanUtils.copyProperties(choice, domain);
                    questionChoiceDomainList.add(domain);
                });
                if (ExerciseType.JUDGMENT.getIntValue().equals(item.getQuestionType())) {
                    Collections.reverse(questionChoiceDomainList);
                }
                exercisesDomain.setChoicelist(questionChoiceDomainList);
            }
            List<ExercisesFileDomain> fileDomainList = new ArrayList<>();
            List<TeacherExercisesFile> exercisesFileList = fileRepository.findByExercisesQuestionId(item.getId());
            exercisesFileList.forEach(file -> {
                ExercisesFileDomain exercisesFileDomain = new ExercisesFileDomain();
                BeanUtils.copyProperties(file, exercisesFileDomain);
                fileDomainList.add(exercisesFileDomain);
            });
            exercisesDomain.setAccessorylist(fileDomainList);
            ExercisesStuAnswer exercisesStuAnswer = exercisesStuAnswerRepository.findByGroupTaskIdAndStuIdAndExercisesId(id, projectGroupTask.getStuId(), item.getId());
            if (!Objects.isNull(exercisesStuAnswer)) {
                exercisesDomain.setStuAnswer(exercisesStuAnswer.getStuAnswer());
            }
//            if (!projectGroupTask.getExercisesIsShowAnswer()){
//                exercisesDomain.setAnswer(null);
//            }
            domainList.add(exercisesDomain);
        });
        return domainList;
    }
    public StuExercisesQuestionListDomain getStuExercisesQuestionListDomain(String id){
        StuExercisesQuestionListDomain stuExercisesQuestionListDomain = new StuExercisesQuestionListDomain();
        List<ExercisesDomain> stuAllQuestionsAndAnswer = findStuAllQuestionsAndAnswer(id);
        Integer total=0;
        Integer error=0;
        for (ExercisesDomain item : stuAllQuestionsAndAnswer) {
            if (item.getQuestionType()==10||item.getQuestionType()==20||item.getQuestionType()==30){
                if(StringUtils.isEmpty(item.getStuAnswer())||!item.getAnswer().equals(item.getStuAnswer())){
                    error++;
                }
                total++;
            }
        }
        List<ExercisesDomain> collect = stuAllQuestionsAndAnswer.stream().filter(item -> {
            if (item.getQuestionType() == 10 || item.getQuestionType() == 20 || item.getQuestionType() == 30) {
                return false;
            } else {
                return true;
            }
        }).collect(Collectors.toList());

        ProjectGroupTask projectGroupTask = taskRepository.findOne(id);

        List<ExercisesStuAnswer> stuAnswerList = exercisesStuAnswerRepository.findByGroupTaskIdAndStuId(id, projectGroupTask.getStuId());
        Integer byTaskId;
        if (StringUtils.isEmpty(projectGroupTask.getWorkOrderId())){
            byTaskId = exercisesRepository.countByTaskId(projectGroupTask.getTaskId());
        }else {
            byTaskId = exercisesRepository.countByTaskId(projectGroupTask.getWorkOrderId());
        }
        if (TaskInforCode.TASK_STATUS_APPROVED.equals(projectGroupTask.getExercisesStatus())){
            stuExercisesQuestionListDomain.setGrade(Integer.parseInt(projectGroupTask.getExercisesFinalGrade()));
            stuExercisesQuestionListDomain.setResult(ReportUtils.getLevel(stuExercisesQuestionListDomain.getGrade()));
            stuExercisesQuestionListDomain.setComment(projectGroupTask.getExercisesComment());
        }else {
            Integer totalGrade = 0;
            for (ExercisesStuAnswer exercisesStuAnswer : stuAnswerList) {
                try {
                    totalGrade += Integer.parseInt(exercisesStuAnswer.getComment());
                } catch (NumberFormatException e) {

                }
            }
            if (byTaskId > 0) {
                stuExercisesQuestionListDomain.setGrade(totalGrade / byTaskId);
                stuExercisesQuestionListDomain.setResult(ReportUtils.getLevel(stuExercisesQuestionListDomain.getGrade()));
            } else {
                stuExercisesQuestionListDomain.setGrade(0);
                stuExercisesQuestionListDomain.setResult("F");
            }
        }
        stuExercisesQuestionListDomain.setTaskStuQuestionsDomainList(collect);
        stuExercisesQuestionListDomain.setTotalNum(total);
        stuExercisesQuestionListDomain.setErrorNum(error);
        return stuExercisesQuestionListDomain;
    }
    //打分
    public void markGrade(MarkGradeDomain domain) {
        ProjectGroupTask projectGroupTask = taskRepository.findOne(domain.getId());
        projectGroupTask.setExercisesStatus(TaskInforCode.TASK_STATUS_APPROVED);
        projectGroupTask.setExercisesFinalGrade(domain.getGrade());
        projectGroupTask.setExercisesComment(domain.getComment());
        taskRepository.save(projectGroupTask);
    }

    public Map<String, Object> getErrorList(String groupTaskId, Long createBy) {
        Map<String, Object> result = new HashMap<>();
        List<ExercisesStuAnswer> exercisesStuAnswerList = exercisesStuAnswerRepository.findByGroupTaskIdAndStuIdAndIsCorrect(groupTaskId, createBy, 0);
        List<String> collect = exercisesStuAnswerList.stream().map(ExercisesStuAnswer::getExercisesId).collect(Collectors.toList());
        if (exercisesStuAnswerList.size() == 0) {
            result.put(ApiReturnConstants.SUCCESS, false);
            result.put(ApiReturnConstants.MESSAGE, "学生未作答");
        }
        List<TeacherExercises> teacherExercisesList = exercisesRepository.findByIdIn(collect);
        List<StuErrorExercisesDomain> domainList = new ArrayList<>();
        teacherExercisesList.forEach(teacherExercises -> {
            if (ExerciseType.MULTIPLE.getIntValue().equals(teacherExercises.getQuestionType()) || ExerciseType.SINGLE.getIntValue().equals(teacherExercises.getQuestionType()) || ExerciseType.JUDGMENT.getIntValue().equals(teacherExercises.getQuestionType())) {
                StuErrorExercisesDomain stuErrorExercisesDomain = new StuErrorExercisesDomain();
                stuErrorExercisesDomain.setExercisesQuestionId(teacherExercises.getId());
                stuErrorExercisesDomain.setOrderNum(teacherExercises.getOrderNum());
                stuErrorExercisesDomain.setErrorType(0);
                domainList.add(stuErrorExercisesDomain);
            }
        });
        if (domainList.size() == 0) {
            result.put(ApiReturnConstants.SUCCESS, false);
            result.put(ApiReturnConstants.MESSAGE, "无错题");
        }
        result.put(ApiReturnConstants.SUCCESS, true);
        result.put(ApiReturnConstants.DATA, domainList);
        return result;
    }

    public Integer[] findChartData(String releaseQuestionId, String stuId) {
        List<ExerciseStuCode> exerciseStuCodeList = exerciseStuCodeRepository.findByExercisesQuestionIdAndStuIdOrderBySubmitTime(releaseQuestionId, stuId);

        List<Integer> scoreList = new ArrayList<>();
        for (ExerciseStuCode score : exerciseStuCodeList) {
            scoreList.add(score.getScore());
        }
        //List<Integer> scoreList = taskStuCodeList.stream().map(TaskStuCode::getScore).collect(Collectors.toList());
        Integer[] scoreArray = scoreList.toArray(new Integer[scoreList.size()]);
        return scoreArray;
    }

    public StuTaskCodeEvaluatingDomain findCodeEvaluating(String releaseQuestionId, String stuId) {
        StuTaskCodeEvaluatingDomain stuTaskReferenceCodeDomain = new StuTaskCodeEvaluatingDomain();
        List<ExerciseStuCode> taskStuCodeList = exerciseStuCodeRepository.findByExercisesQuestionIdAndStuIdOrderBySubmitTimeDesc(releaseQuestionId, stuId);
        List<ExerciseStuCode> collect = taskStuCodeList.stream().sorted(Comparator.comparing(ExerciseStuCode::getSubmitTime)).collect(Collectors.toList());
        stuTaskReferenceCodeDomain.setCodeRow(collect.size() == 0 ? 0 : collect.get(0).getCodeRowNum());
        stuTaskReferenceCodeDomain.setErrorNum(collect.size() == 0 ? 0 : collect.get(0).getIsError() == null ? 0 : collect.get(0).getIsError());
        stuTaskReferenceCodeDomain.setSubmitCount(taskStuCodeList.size());
        stuTaskReferenceCodeDomain.setSubmitTime(collect.size() == 0 ? "" : collect.get(0).getSubmitTime().toString());
        return stuTaskReferenceCodeDomain;
    }

    public ExercisesStuStatistics findEvaluationData(String releaseQuestionId, String stuId) {
        ExercisesStuStatistics exercisesStuStatistics = exercisesStuStatisticsRepository.findByExercisesQuestionIdAndStuId(releaseQuestionId, stuId);

        return exercisesStuStatistics;
    }

    public FindTaskTopicDomain findProgrammeAndRubric(String exercisesQuestionId, String releaseTaskId) {
        FindTaskTopicDomain findTaskTopicDomain = new FindTaskTopicDomain();
        TeacherExercises teacherExercises = exercisesRepository.findOne(exercisesQuestionId);
        List<TeacherExercises> teacherExercisesList = exercisesRepository.findByTaskIdAndQuestionType(releaseTaskId, 60);
        findTaskTopicDomain.setQuestionNum(teacherExercises.getQuestionContent());
        findTaskTopicDomain.setRestsTaskTopicDomains(teacherExercisesList);
        return findTaskTopicDomain;
    }

    public StuTaskReferenceCodeDomain findReferenceCode(String exercisesQuestionId, String stuId) {
        StuTaskReferenceCodeDomain stuTaskReferenceCodeDomain = new StuTaskReferenceCodeDomain();
        TeacherExercises teacherExercises = exercisesRepository.findOne(exercisesQuestionId);
        List<ExerciseStuCode> taskStuCodeList = exerciseStuCodeRepository.findByExercisesQuestionIdAndStuIdOrderBySubmitTimeDesc(exercisesQuestionId, stuId);
        List<String> codeList = taskStuCodeList.stream().map(ExerciseStuCode::getSubmitCode).collect(Collectors.toList());
        stuTaskReferenceCodeDomain.setStuCode(codeList);
        stuTaskReferenceCodeDomain.setReferenceCode(teacherExercises.getReferenceCode());
        return stuTaskReferenceCodeDomain;
    }
    RowMapper<QuestionTypeAvgDomain> avgDomainRowMapper = new RowMapper<QuestionTypeAvgDomain>() {

        @Override
        public QuestionTypeAvgDomain mapRow(ResultSet rs, int rowNum) throws SQLException {
            // TODO Auto-generated method stub
            QuestionTypeAvgDomain domain = new QuestionTypeAvgDomain();
            domain.setType(rs.getInt(1));
            domain.setGrade(rs.getDouble(2));
            return domain;
        }
    };
    public Map<String, Object> getAvg(String groupTaskId,Long stuId) {
        Map map = new HashMap();
        String sql = "SELECT r.question_type type,AVG(t.`comment`) avg_grade FROM c_exercises_stu_answer t RIGHT JOIN c_exercises r ON t.exercises_id=r.ID WHERE t.group_task_id='" + groupTaskId + "' AND t.stu_id='"+stuId+"' GROUP BY r.question_type";
        List<QuestionTypeAvgDomain> info = pageJdbcUtil.getInfo(sql, avgDomainRowMapper);
        info.forEach(item -> {
            map.put(item.getType(), item.getGrade()==null?0:item.getGrade());
        });
        return map;
    }
    public Map<String, Object> getStuComment(String groupTaskId) {
        Map<String, Object> map = new HashMap();
        ProjectGroupTask one = taskRepository.findOne(groupTaskId);
        map.put(ApiReturnConstants.SUCCESS,true);
        map.put("comment",one.getExercisesComment());
        map.put("grade",one.getExercisesFinalGrade());
        return map;
    }
    public Map<String, Object> getIsSetTime(String groupTaskId) {
        Map<String, Object> map = new HashMap();
        ProjectGroupTask one = taskRepository.findOne(groupTaskId);
        map.put(ApiReturnConstants.SUCCESS,true);
        map.put("isSetTime",one.getIsSetTime());
        map.put("duration",one.getDuration());
        return map;
    }
}